package com.zmc.admin.infrastructure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmc.admin.infrastructure.constant.UserConstants;
import com.zmc.admin.infrastructure.dao.SysRoleDao;
import com.zmc.admin.infrastructure.entity.SysRoleDeptEntity;
import com.zmc.admin.infrastructure.entity.SysUserRoleEntity;
import com.zmc.admin.infrastructure.bean.query.SysRoleQuery;
import com.zmc.admin.infrastructure.service.SysRoleDeptService;
import com.zmc.admin.infrastructure.service.SysUserRoleService;
import com.zmc.common.annotation.PreventRepeatSubmit;
import com.zmc.common.enums.RequestSourceEnum;
import com.zmc.common.utils.PageUtils;
import com.zmc.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zmc.admin.infrastructure.entity.SysRoleEntity;
import com.zmc.admin.infrastructure.service.SysRoleService;
import org.springframework.transaction.annotation.Transactional;


@Service("sysRoleService")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {

    @Autowired
    private SysRoleDeptService roleDeptService;

    @Autowired
    private SysUserRoleService userRoleService;

    @Override
    public List<SysRoleEntity> selectRolePermissionByUserId(Long userId) {
        return baseMapper.selectRolePermissionByUserId(userId);
    }

    @Override
    public List<SysRoleEntity> selectRolesByUserName(String userName) {
        return baseMapper.selectRolesByUserName(userName);
    }

    @Override
    public PageUtils pageRoleList(SysRoleQuery query) {
        Page<SysRoleEntity> page = baseMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), getWrapper(query));
        return new PageUtils(page);
    }

    @Override
    public List<SysRoleEntity> selectRoleList(SysRoleQuery query) {
        return baseMapper.selectList(getWrapper(query));
    }



    @Override
    public boolean checkRoleNameUnique(SysRoleEntity role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        SysRoleEntity info = baseMapper.checkRoleNameUnique(role.getRoleName());
        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean checkRoleKeyUnique(SysRoleEntity role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        SysRoleEntity info = baseMapper.checkRoleKeyUnique(role.getRoleKey());
        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    @Transactional
    public void authDataScope(SysRoleEntity role) {
        // 修改角色信息
        updateById(role);
        // 删除角色与部门关联
        roleDeptService.deleteRoleDeptByRoleId(role.getRoleId());
        // 新增角色和部门信息（数据权限）
        insertRoleDept(role);
    }

    @Override
    @Transactional
    public void deleteAuthUser(SysUserRoleEntity userRole) {
        baseMapper.deleteUserRoleInfo(userRole);
    }

    @Override
    @Transactional
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void deleteAuthUsers(Long roleId, Long[] userIds) {
        baseMapper.deleteUserRoleInfos(roleId, userIds);
    }

    @Override
    @Transactional
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public void insertAuthUsers(Long roleId, Long[] userIds) {
        List<SysUserRoleEntity> list = new ArrayList<SysUserRoleEntity>();
        for (Long userId : userIds)
        {
            SysUserRoleEntity ur = new SysUserRoleEntity();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        userRoleService.saveBatch(list);
    }

    @Override
    public List<SysRoleEntity> selectRolesByUserId(Long userId) {
        List<SysRoleEntity> userRoles = baseMapper.selectRolePermissionByUserId(userId);
        List<SysRoleEntity> roles = list();
        for (SysRoleEntity role : roles)
        {
            for (SysRoleEntity userRole : userRoles)
            {
                if (role.getRoleId().longValue() == userRole.getRoleId().longValue())
                {
                    role.setDelFlag("0");
                    break;
                }
            }
        }
        return roles;
    }

    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        return baseMapper.selectRoleListByUserId(userId);
    }

    @Override
    public SysRoleEntity queryByRoleKey(String roleKey) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleEntity::getRoleKey, roleKey).last(" limit 1");
        return getOne(wrapper);
    }

    /**
     * 新增角色部门信息(数据权限)
     *
     * @param role 角色对象
     */
    public void insertRoleDept(SysRoleEntity role) {
        int rows = 1;
        // 新增角色与部门（数据权限）管理
        List<SysRoleDeptEntity> list = new ArrayList<SysRoleDeptEntity>();
        for (Long deptId : role.getDeptIds()) {
            SysRoleDeptEntity rd = new SysRoleDeptEntity();
            rd.setRoleId(role.getRoleId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        roleDeptService.saveBatch(list);
    }

    private LambdaQueryWrapper<SysRoleEntity> getWrapper(SysRoleQuery query) {
        LambdaQueryWrapper<SysRoleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(query.getRoleKey()), SysRoleEntity::getRoleKey, query.getRoleKey())
                .eq(StringUtils.isNotEmpty(query.getRoleName()), SysRoleEntity::getRoleName, query.getRoleName())
                .eq(StringUtils.isNotEmpty(query.getStatus()), SysRoleEntity::getStatus, query.getStatus())
                .ge(StringUtils.isNotEmpty(query.getBeginTime()), SysRoleEntity::getCreateTime, query.getBeginTime())
                .le(StringUtils.isNotEmpty(query.getEndTime()), SysRoleEntity::getCreateTime, query.getEndTime());
        return wrapper;
    }

}